/** m2settings is a GUI to configure Maven 2 settings.xml 
 * 
 *  Copyright (C) 2007 Regis Decamps <decamps@users.sf.net>
 * 
 *  This file is part of m2settings.
 *
 *  m2settings is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version. 
 *
 *  Foobar is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  or read it online http://www.gnu.org/licenses/gpl.txt
 *
 **/
/*
 * Permissions.java
 *
 * Created on April 21, 2007, 4:36 PM
 *
 */

package info.decamps.m2settings.beans;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import javax.swing.text.NumberFormatter;

/**
 * This class manages Unix-style permissions.
 * @author regis
 */
public class Permissions {
    public final static int PERM_USER=2;
    public final static int PERM_GROUP=1;
    public final static int PERM_OTHER=0;
    
    public final static int PERM_R=2;
    public final static int PERM_W=1;
    public final static int PERM_X=0;
    
    private static final boolean[] PERMS_NONE_UGO={false,false,false};
    private static final boolean[] PERMS_USER_DEFAULT={false,true,true};
    private static final boolean[] PERMS_GROUP_DEFAULT={false,true,true};
    private static final boolean[] PERMS_OTHER_DEFAULT={false,false,true};
    private boolean[][] permissions={PERMS_OTHER_DEFAULT,PERMS_GROUP_DEFAULT,PERMS_USER_DEFAULT};
    private NumberFormat numberFormat;
    
    /** Creates a new instance of Permissions.
     * No permission granted by default.
     */
    public Permissions() {
        numberFormat=new DecimalFormat("000");
    }
    
    /**
     * Creates a Permissions descriptor based on a numeric mode.
     *
     *A numeric mode is from one to four octal digits (0-7), derived by adding up the bits with  values  4,  2,
     * and  1.  Any omitted digits are assumed to be leading zeros.  The first digit selects the set-user-ID (4)
     * and set-group-ID (2) and save text image [`sticky'] (1) attributes.  The second digit selects permissions
     * for  the  user who owns the file: read (4), write (2), and execute (1); the third selects permissions for
     * other users in the file's group, with the same values; and the fourth for other users not in  the  file's
     * group, with the same values.
     *
     */
    public Permissions(String perms777) {
        this();
        if (perms777!=null) {
            setPermissions777(perms777);
        }
    }
    
    /** Print Permissions in a rwxrwxrwx form */
    public String toStringRwxRwxRwx() {
        return UGOToRWXString(permissions[PERM_USER])+
                UGOToRWXString(permissions[PERM_GROUP])+
                UGOToRWXString(permissions[PERM_OTHER]);
    }
    
    /**
     *print rwx String of a user/group/other permission array
     */
    protected static String UGOToRWXString(boolean[] ugoPerm) {
        String rwx=(ugoPerm[PERM_R]) ? "r" : "-";
        rwx+=(ugoPerm[PERM_W]) ? "w" : "-";
        rwx+=(ugoPerm[PERM_X]) ? "x" : "-";
        return rwx;
    }
    
    public String toString() {
        int val=getUserIntPermissions()*100+
                getGroupIntPermissions()*10+
                getOtherIntPermissions();
        return numberFormat.format(val);
    }
    public void setPermissions777(String perms777) {
        setUserIntPermissions(UGOPermissions(PERM_USER, perms777));
        setGroupIntPermissions(UGOPermissions(PERM_GROUP,perms777));
        setOtherIntPermissions(UGOPermissions(PERM_OTHER,perms777));
    }
    /**
     * Given a Unix permission (777 form), return the character permission for
     * user/group/other.
     *@param ugo user (PERM_USER), group (PERM_GOUP) or other (PERM_OTHER)
     *@param perm777 Unix permissions in the from 777
     */
    private static int UGOPermissions(int ugo,String perm777) {
        return Integer.parseInt(perm777.substring(perm777.length()-ugo-1,
                perm777.length()-ugo));
    }
    
    /* integer permissinos */
    public int getUserIntPermissions() {
        boolean[] userPerms=permissions[PERM_USER];
        return intPermissions(userPerms);
    }
    public int getGroupIntPermissions() {
        boolean[] groupPerms=permissions[PERM_GROUP];
        return intPermissions(groupPerms);
    }
    public int getOtherIntPermissions() {
        boolean[] otherPerms=permissions[PERM_OTHER];
        return intPermissions(otherPerms);
    }
    protected static int intPermissions(boolean[] perms) {
        int retval=0;
        retval+=(perms[PERM_R]) ? 1 << PERM_R :0;
        retval+=(perms[PERM_W]) ? 1 << PERM_W :0;
        retval+=(perms[PERM_X]) ? 1 << PERM_X :0;
        return retval;
    }
    public void setUserIntPermissions(int perm) {
        permissions[PERM_USER]=intPermissionsToBooleans(perm);
    }
    public void setGroupIntPermissions(int perm) {
        permissions[PERM_GROUP]=intPermissionsToBooleans(perm);
    }
    public void setOtherIntPermissions(int perm) {
        permissions[PERM_OTHER]=intPermissionsToBooleans(perm);
    }
    protected static boolean[] intPermissionsToBooleans(int perm) {
        boolean[] ugoPerms=new boolean[3];
        ugoPerms[PERM_X]= (perm % 2 ==1 ) ? true : false;
        perm=perm/2;
        ugoPerms[PERM_W]= (perm % 2 ==1 ) ? true : false;
        perm=perm/2;
        ugoPerms[PERM_R]= (perm % 2 ==1 ) ? true : false;
        return ugoPerms;
    }
    
    /* access byte by byte */
    public boolean isUserRead() {
        return permissions[PERM_USER][PERM_R];
    }
    
    public void setUserRead(boolean userRead) {
        permissions[PERM_USER][PERM_R] = userRead;
    }
    
    public boolean isUserWrite() {
        return permissions[PERM_USER][PERM_W];
    }
    
    public void setUserWrite(boolean userWrite) {
        permissions[PERM_USER][PERM_W] = userWrite;
    }
    
    public boolean isUserExec() {
        return permissions[PERM_USER][PERM_X];
    }
    
    public void setUserExec(boolean userExec) {
        permissions[PERM_USER][PERM_X] = userExec;
    }
    
    public boolean isGroupRead() {
        return permissions[PERM_GROUP][PERM_R];
    }
    
    public void setGroupRead(boolean groupRead) {
        permissions[PERM_GROUP][PERM_R] = groupRead;
    }
    
    public boolean isGroupWrite() {
        return permissions[PERM_GROUP][PERM_W];
    }
    
    public void setGroupWrite(boolean groupWrite) {
        permissions[PERM_GROUP][PERM_W] = groupWrite;
    }
    
    public boolean isGroupExec() {
        return permissions[PERM_GROUP][PERM_X];
    }
    
    public void setGroupExec(boolean groupExec) {
        permissions[PERM_GROUP][PERM_X] = groupExec;
    }
    
    public boolean isOtherRead() {
        return permissions[PERM_OTHER][PERM_R];
    }
    
    public void setOtherRead(boolean otherRead) {
        permissions[PERM_OTHER][PERM_R] = otherRead;
    }
    
    public boolean isOtherWrite() {
        return permissions[PERM_OTHER][PERM_W];
    }
    
    public void setOtherWrite(boolean otherWrite) {
        permissions[PERM_OTHER][PERM_W] = otherWrite;
    }
    
    public boolean isOtherExec() {
        return permissions[PERM_OTHER][PERM_X];
    }
    
    public void setOtherExec(boolean otherExec) {
        permissions[PERM_OTHER][PERM_X] = otherExec;
    }
    
}
